#pragma once
#include "BNModel.h"
#include "ShaderQueueSuit_Common.h"
#include <GLFW/glfw3.h>
#include <cstdlib>   //标准库标准通用工具函数
#include <functional>//标准库与函数对象相关的模板类和函数
#include <iostream>  //标准库输入输出头文件
#include <mutex>
#include <stdexcept>//标准库异常处理文件
#include <thread>
#include <vulkan/vulkan.h>//引用Vulkan的头文件

class VulkanDemoApp {
public:
    static constexpr int WIDTH = 800;
    static constexpr int HEIGHT = 600;

    static uint32_t screenWidth; // 屏幕宽度
    static uint32_t screenHeight;// 屏幕高度
    // 窗口辅助结构体
    GLFWwindow *window;
    std::vector<const char *> instanceExtensionNames;     // 需要使用的实例扩展名称列表
    VkInstance instance;                                  // Vulkan实例
    uint32_t gpuCount;                                    // 物理设备数量
    std::vector<VkPhysicalDevice> gpus;                   // 物理设备列表
    uint32_t queueFamilyCount;                            // 物理设备对应的队列族数量
    std::vector<VkQueueFamilyProperties> queueFamilyProps;// 物理设备对应的队列族属性列表
    uint32_t queueGraphicsFamilyIndex;                    // 支持图形作业的队列族索引
    VkQueue queueGraphics;                                // 支持图形作业的队列
    uint32_t queuePresentFamilyIndex;                     // 支持呈现作业的队列族索引
    std::vector<const char *> deviceExtensionNames;       // 所需的设备扩展名称列表
    VkDevice device;                                      // 逻辑设备
    VkCommandPool cmdPool;                                // 命令池
    VkCommandBuffer cmdBuffer;                            // 命令缓冲
    VkCommandBufferBeginInfo cmd_buf_info;                // 命令缓冲启动信息
    VkCommandBuffer cmd_buffers[1];                       // 供提交执行的命令缓冲数组
    VkSubmitInfo submit_info[1];                          // 命令缓冲提交执行信息数组
    VkSurfaceKHR surface;                                 // KHR表面
    std::vector<VkFormat> formats;                        // KHR表面支持的格式
    VkSurfaceCapabilitiesKHR surfCapabilities;            // 表面的能力
    uint32_t presentModeCount;                            // 呈现模式数量
    std::vector<VkPresentModeKHR> presentModes;           // 呈现模式列表
    VkExtent2D swapchainExtent;                           // 交换链尺寸
    VkSwapchainKHR swapChain;                             // 交换链

    uint32_t swapchainImageCount;                     // 交换链中的图像数量
    std::vector<VkImage> swapchainImages;             // 交换链中的图像列表
    std::vector<VkImageView> swapchainImageViews;     // 交换链对应的的图像视图列表
    VkFormat depthFormat;                             // 深度图像格式
    VkFormatProperties depthFormatProps;              // 物理设备支持的深度格式属性
    VkImage depthImage;                               // 深度缓冲图像
    VkPhysicalDeviceMemoryProperties memoryProperties;// 物理设备内存属性
    VkDeviceMemory memDepth;                          // 深度缓冲图像对应的内存
    VkImageView depthImageView;                       // 深度缓冲图像视图
    VkSemaphore imageAcquiredSemaphore;               // 渲染目标图像获取完成信号量
    uint32_t currentBuffer;                           // 从交换链中获取的当前渲染用图像对应的缓冲编号
    VkRenderPass renderPass;                          // 渲染过程
    VkClearValue clear_values[2];                     // 渲染过程用清除帧缓冲深度、颜色附件的数据
    VkRenderPassBeginInfo rp_begin;                   // 渲染过程启动信息
    VkFence taskFinishFence;                          // 等待任务完毕的栅栏
    VkPresentInfoKHR present;                         // 呈现信息
    VkFramebuffer *framebuffers;                      // 帧缓冲序列首指针
    static ShaderQueueSuit_Common *sqsCL;
    BNModel *bnModelA;
    BNModel *bnModelB;
    std::mutex myLock;//访问中间传输区顶点数据的锁

    //拖动光标的变化量
    static double cursorDeltaX;
    static double cursorDeltaY;

    //当前贯标的坐标
    static double currentCursorX;
    static double currentCursorY;

    void initVulkanInstance();            // 创建Vulkan实例
    void enumerateVulkanPhysicalDevices();// 初始化物理设备
    void createVulkanDevices();           // 创建逻辑设备
    void createVulkanCommandBuffer();     // 创建命令缓冲
    void createVulkanSwapChain();         // 初始化交换链
    void createVulkanDepthBuffer();       // 创建深度缓冲相关
    void createRenderPass();              // 创建渲染过程
    void initQueue();                     // 获取设备中支持图形作业的队列
    void createFrameBuffer();             // 创建帧缓冲
    void createDrawableObject();       // 创建绘制用物体
    void drawObject();                 // 执行场景中的物体绘制
    void initTextures();
    void initPipeline();               // 初始化管线
    void createFence();                // 创建栅栏
    void initPresentInfo();            // 初始化呈现信息
    static void initMatrix();          // 初始化矩阵
    void flushUniformBuffer();         // 将一致变量数据送入缓冲
    void flushTexToDesSet() const;     // 将纹理等数据与描述集关联
    void destroyFence() const;         // 销毁栅栏
    void destroyPipeline() const;      // 销毁管线
    void destroyDrawableObject() const;// 销毁绘制用物体
    void destroyTextures();
    void destroyFrameBuffer() const;      // 销毁帧缓冲
    void destroyRenderPass() const;       // 销毁渲染过程
    void destroyVulkanDepthBuffer() const;// 销毁深度缓冲相关
    void destroyVulkanSwapChain();        // 销毁交换链
    void destroyVulkanCommandBuffer();    // 销毁命令缓冲
    void destroyVulkanDevices() const;    // 销毁逻辑设备
    void destroyVulkanInstance() const;   // 销毁实例
    void updateBNGGDH();                  //用于更新骨骼动画的方法

    // 三角形应用运行函数
    void run();

    bool frameBufferResized = false;

private:
    // 初始化窗体
    void initWindow();

    // 初始化Vulkan
    void initVulkan();

    // 图形程序渲染流程主循环
    void mainLoop();

    // 后续清理工作
    void cleanup();

    void destroyWindow() const;

    static void frameBufferResizeCallback(GLFWwindow *window, int width, int height);

    std::vector<const char *> static get_required_extensions();

    std::thread animationThread;             //粒子系统线程
    static bool isAnimationThreadShouldClose;//粒子系统线程是否应该被关闭
};
